﻿using LightCAD.Core.Elements;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace LightCAD.Core
{
    [JsonDerivedType(typeof(Point), typeDiscriminator: nameof(Point))]
    [JsonDerivedType(typeof(LcLine), typeDiscriminator: nameof(LcLine))]
    [JsonDerivedType(typeof(LcCircle), typeDiscriminator: nameof(LcCircle))]
    [JsonDerivedType(typeof(LcGroup), typeDiscriminator: nameof(LcGroup))]
    [JsonDerivedType(typeof(LcBlockRef), typeDiscriminator: nameof(LcBlockRef))]

    public partial class LcElement
    {
        public string GetBaseType()
        {
            if (this.Type.ClassType.IsSubclassOf(typeof(DirectComponent)))
            {
                return nameof(DirectComponent);
            }
            else if (this.Type.ClassType.IsSubclassOf(typeof(LcComponentInstance)))
            {
                return nameof(LcComponentInstance);
            }
            else 
            {
                return nameof(LcElement);
            }
          
        }
        public virtual void WriteBaseProperties(Utf8JsonWriter writer, JsonSerializerOptions soptions)
        {
            writer.WriteIdProperty(nameof(this.Id), this.Id);
            writer.WriteStringProperty("TypeName", this.Type.Name);
            writer.WriteStringProperty("BaseType", this.GetBaseType());
            if (this.Layer != "0")
            {
                writer.WriteStringProperty(nameof(this.Layer), this.Layer);
            }
            if (this.Color != ValueFrom.ByLayer)
            {
                writer.WriteStringProperty(nameof(this.Color), this.Color);
            }
            if (this.LineType != ValueFrom.ByLayer)
            {
                writer.WriteStringProperty(nameof(this.LineType), this.LineType);
            }
            if (this.LineTypeScale != 1.0)
            {
                writer.WriteNumberProperty(nameof(this.LineTypeScale),this.LineTypeScale);
            }
            if (this.LineWeight != ValueFrom.ByLayer)
            {
                writer.WriteStringProperty(nameof(this.LineWeight), this.LineWeight);
            }
            if (this.Transparency != ValueFrom.ByLayer)
            {
                writer.WriteStringProperty(nameof(this.Transparency), this.Transparency);
            }
            if (this.PlotStyleName != "ByColor")
            {
                writer.WriteStringProperty(nameof(this.PlotStyleName), this.PlotStyleName);
            }
            if (!this.Visible)
            {
                writer.WriteBoolProperty(nameof(this.Visible), this.Visible);
            }
            if (this.UserData != null && this.UserData.Count > 0)
            {
                writer.WriteDictionaryProperty<object>(nameof(this.UserData), this.UserData, soptions);
            }
        }


        public virtual void WriteProperties(Utf8JsonWriter writer, JsonSerializerOptions soptions)
        {
        }
        public virtual void ReadBaseProperties(ref JsonElement jele)
        {
            this.Id = jele.ReadIdProperty(nameof(this.Id));
            this.Document.IdCreator.RestObjectIdMax(this.Id);
            var layer = jele.ReadStringProperty(nameof(this.Layer));
            this.Layer = layer ?? "0";

            var color = jele.ReadStringProperty(nameof(this.Color));
            this.Color = color ?? ValueFrom.ByLayer;

            var lineType = jele.ReadStringProperty(nameof(this.LineType));
            this.LineType = lineType ?? ValueFrom.ByLayer;


            var lineTypeScale = jele.ReadDoubleProperty(nameof(this.LineTypeScale));
            this.LineTypeScale = lineTypeScale == 0 ? 1.0 : lineTypeScale;

            var lineWeight = jele.ReadStringProperty(nameof(this.LineWeight));
            this.LineWeight = lineWeight ?? ValueFrom.ByLayer;

            var transparency = jele.ReadStringProperty(nameof(this.Transparency));
            this.Transparency = transparency ?? ValueFrom.ByLayer;

            var plotStyleName = jele.ReadStringProperty(nameof(this.PlotStyleName));
            this.PlotStyleName = plotStyleName ?? ValueFrom.ByColor;

            var visible = jele.ReadBoolProperty(nameof(this.Visible));
            this.Visible = visible ?? true;

            var exist = jele.TryGetProperty(nameof(this.UserData), out JsonElement userDataProp);
            if (exist && !userDataProp.NullOrUndefined())
            {
                this.UserData = JsonSerializer.Deserialize<Dictionary<string, object>>(userDataProp);
            }
        }

        public virtual void ReadProperties(ref JsonElement jele)
        {

        }
    }
}
